package com.mbc.rmt.manager;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRResultSetDataSource;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.util.JRLoader;

import com.mbc.common.CommonSingleton;
import com.mbc.common.dao.CommonDAOFactory;
import com.mbc.common.dao.CurrencyRateDAO;
import com.mbc.common.dao.CurrencyRateDetailDAO;
import com.mbc.common.dao.LogDAO;
import com.mbc.common.entities.CurrencyRate;
import com.mbc.common.entities.CurrencyRateDetail;
import com.mbc.common.entities.Log;
import com.mbc.common.exception.DataDuplicationException;
import com.mbc.common.manager.AbstractMgr;
import com.mbc.common.utils.KeyGenerator;
import com.mbc.rmt.dao.AllBranchOpeningDAO;
import com.mbc.rmt.dao.BranchBalanceDAO;
import com.mbc.rmt.dao.RemittanceDAOFactory;
import com.mbc.rmt.entities.AllBranchOpening;
import com.mbc.rmt.entities.AllBranchOpeningRpt;
import com.mbc.rmt.entities.BranchBalance;

public class AllBranchOpeningMgr extends AbstractMgr {

	private AllBranchOpeningDAO allBranchOpeningDAO;
	private CurrencyRateDAO currencyrateDAO;
	private CurrencyRateDetailDAO rateDetailDAO;
	private BranchBalanceDAO branchBalanceDAO;
	private LogDAO logDAO;

	public AllBranchOpeningMgr() {

	}

	public AllBranchOpeningMgr(String sessionId) {
		this.sessionId = sessionId;
	}

	public void create(AllBranchOpening entity, ArrayList<Long> removeKeyList) throws Exception {
		openConnection();
		try {
			beginTransaction();
			allBranchOpeningDAO = RemittanceDAOFactory.getAllBranchOpeningDAO(getConnection());
			currencyrateDAO = CommonDAOFactory.getCurrencyRateDAO(dbManager.getConnection());
			rateDetailDAO = CommonDAOFactory.getCurrencyRateDetailDAO(dbManager.getConnection());
			branchBalanceDAO = RemittanceDAOFactory.getBranchBalanceDAO(dbManager.getConnection());
			logDAO = CommonDAOFactory.getLogDAO(getConnection());
			//Delete
			if(removeKeyList != null)
				for(long key : removeKeyList){
					
					AllBranchOpening deletebranchOpening = new AllBranchOpening();
					deletebranchOpening.setAllBranchOpeningId(key);
					deletebranchOpening = allBranchOpeningDAO.getAllBranchOpening(deletebranchOpening);
					
					if( deletebranchOpening != null)
					{
						BranchBalance l_balance = new BranchBalance();
				        l_balance.setBranch_id(deletebranchOpening.getBranchId());
				        l_balance.setCurrencyid(deletebranchOpening.getCurrencyId());
				        l_balance = branchBalanceDAO.getInfo(l_balance);
				        
						if(deletebranchOpening.getSourceReceivableAmt() !=0)
						{
							l_balance.setOpeningbalance(l_balance.getOpeningbalance() - deletebranchOpening.getSourceReceivableAmt());
							l_balance.setCurrentbalance(l_balance.getCurrentbalance() - deletebranchOpening.getSourceReceivableAmt());
							
						}
						else
						{
							l_balance.setOpeningbalance(l_balance.getOpeningbalance() + deletebranchOpening.getSourcePayableAmt());
							l_balance.setCurrentbalance(l_balance.getCurrentbalance() + deletebranchOpening.getSourcePayableAmt());
							
						}
						branchBalanceDAO.update(l_balance);
				
					}
					
					//Tran Delete
					AllBranchOpening branchOpening = new AllBranchOpening();
					branchOpening.setAllBranchOpeningId(key);
					
					Log l_logentity = new Log();
					l_logentity.setTablename("AllBranchOpening");
					l_logentity.setLogkey(KeyGenerator.generateKey(getConnection()));
					l_logentity.setKey(key);
					l_logentity.setUserid(entity.getUserId());
					l_logentity.setLogstatus(Log.__DELETE_DATA);
					logDAO.getData(l_logentity);
					
					allBranchOpeningDAO.delete(branchOpening);
			}
			//Save & Update
			
			for (AllBranchOpening detail : entity.getAllBranchOpeningList()) {
				
				CurrencyRate l_currencyrate = null;
				CurrencyRateDetail l_currencyrateDetail = new CurrencyRateDetail();
				if(detail.getRate() !=1){
					l_currencyrateDetail = rateDetailDAO.findLatest(detail.getCurrencyRateId());
					if ( l_currencyrateDetail.getRate() != detail.getRate()){
				   
					   l_currencyrateDetail.setCurrencyRateDetailId(KeyGenerator.generateKey(getConnection()));
					   l_currencyrateDetail.setCurrencyRateId(detail.getCurrencyRateId());
					   l_currencyrateDetail.setRate(detail.getRate());
					   l_currencyrateDetail.seteDateTime(new Date());
					   rateDetailDAO.create(l_currencyrateDetail);
					   
					   Log l_logentity = new Log();
					   l_logentity.setTablename("CurrencyRateDetail");
					   l_logentity.setLogkey(KeyGenerator.generateKey(getConnection()));
					   l_logentity.setKey(l_currencyrateDetail.getCurrencyRateDetailId());
					   l_logentity.setLogstatus(Log.__SAVE_DATA);
					   logDAO.getData(l_logentity);
					}
				  }
				
				//Save
				
				if(detail.getAllBranchOpeningId() ==0){ // Save
					detail.setAllBranchOpeningId(KeyGenerator
							.generateKey(getConnection()));
					detail.setDefaultBranchId(entity.getDefaultBranchId());
					detail.setUserId(entity.getUserId());
					allBranchOpeningDAO.create(detail);
					
					Log l_logentity = new Log();
					l_logentity.setTablename("AllBranchOpening");
					l_logentity.setLogkey(KeyGenerator.generateKey(getConnection()));
					l_logentity.setKey(detail.getAllBranchOpeningId());
					l_logentity.setUserid(entity.getUserId());
					l_logentity.setLogstatus(Log.__SAVE_DATA);
					logDAO.getData(l_logentity);
				
				BranchBalance balance = new BranchBalance();
				balance.setBranch_id(detail.getBranchId());
				balance.setCurrencyid(detail.getCurrencyId());
				balance = branchBalanceDAO.getInfo(balance);
				
				if(balance == null)
				{
					balance = new BranchBalance();
					balance.setBranchbalance_id(KeyGenerator.generateKey(getConnection()));
					balance.setBranch_id(detail.getBranchId());
					balance.setCurrencyid(detail.getCurrencyId());
					if(detail.getSourceReceivableAmt() != 0)
					{
						balance.setOpeningbalance(+detail.getSourceReceivableAmt());
					    balance.setCurrentbalance(+detail.getSourceReceivableAmt());
					} 
					else
					{
						balance.setOpeningbalance(-detail.getSourcePayableAmt());
						balance.setCurrentbalance(-detail.getSourcePayableAmt());
					}
					branchBalanceDAO.create(balance);
				}
				else{
					if(detail.getSourceReceivableAmt() !=0)
					{
						balance.setOpeningbalance(balance.getOpeningbalance()+detail.getSourceReceivableAmt());
						balance.setCurrentbalance(balance.getCurrentbalance()+detail.getSourceReceivableAmt());
					}
					else
					{
						balance.setOpeningbalance(balance.getOpeningbalance()-detail.getSourcePayableAmt());
						balance.setCurrentbalance(balance.getCurrentbalance()-detail.getSourcePayableAmt());
					}
					branchBalanceDAO.update(balance);
				  }
				}
				//End Save
			   else{ // Update
					
				   BranchBalance balance = new BranchBalance();
				   double sourceRAmt = 0;
				   double tempSourceRAmt =0;
				   double sourcePAmt =0;
				   double tempSourcePAmt =0;
				   long branchid =0;
				   long tempbranchid =0;
				   long currencyid =0;
				   long tempcurrencyid =0;
				   
				   sourceRAmt = detail.getSourceReceivableAmt();
				   sourcePAmt = detail.getSourcePayableAmt();
				   branchid = detail.getBranchId();
				   currencyid = detail.getCurrencyId();
				   
				   AllBranchOpening tempentity = new AllBranchOpening();
				   tempentity = allBranchOpeningDAO.getAllBranchOpening(detail);
//				   for(AllBranchOpening tempDetail : entity.getAllBranchOpeningList())
//				   {
					   tempSourceRAmt = tempentity.getSourceReceivableAmt();
					   tempSourcePAmt = tempentity.getSourcePayableAmt();
					   tempbranchid = tempentity.getBranchId();
					   tempcurrencyid = tempentity.getCurrencyId();
					   
					   if(tempbranchid == branchid && tempcurrencyid == currencyid )
					   {
						   balance.setBranch_id(detail.getBranchId());
						   balance.setCurrencyid(detail.getCurrencyId());
						   balance = branchBalanceDAO.getInfo(balance);
						   
						   if(detail.getSourceReceivableAmt() !=0 )
						   {
							   balance.setOpeningbalance((balance.getOpeningbalance()-tempSourceRAmt) + sourceRAmt);
							   balance.setCurrentbalance((balance.getCurrentbalance()-tempSourceRAmt) + sourceRAmt);
						   }
						   else
						   {
							   balance.setOpeningbalance((balance.getOpeningbalance()+tempSourcePAmt) - sourcePAmt);
							   balance.setCurrentbalance((balance.getCurrentbalance()+tempSourcePAmt) - sourcePAmt);
						   }
						   branchBalanceDAO.update(balance);
					   }
					   else
					   {
						   double amount =0;
						   balance.setBranch_id(tempbranchid);
						   balance.setCurrencyid(tempcurrencyid);
						   balance = branchBalanceDAO.getInfo(balance);
						   if(detail.getSourceReceivableAmt() !=0)
						   {
							   amount =balance.getOpeningbalance()- tempSourceRAmt;
							   amount =balance.getCurrentbalance()- tempSourceRAmt;
						   }
						   else
						   {
							   amount =balance.getOpeningbalance()+ tempSourcePAmt;
							   amount =balance.getCurrentbalance()+ tempSourcePAmt;
						   }
						   balance.setOpeningbalance(amount);
						   balance.setCurrentbalance(amount);
						   branchBalanceDAO.update(balance);
						   
						   balance.setBranch_id(detail.getBranchId());
						   balance.setCurrencyid(detail.getCurrencyId());
						   balance = branchBalanceDAO.getInfo(balance);
						   if(balance != null)
						   {
							   if(detail.getBranchId() == tempbranchid && detail.getCurrencyId() == tempcurrencyid)
							   {
								   if(detail.getSourceReceivableAmt() !=0)
								   {
									   balance.setOpeningbalance(amount + sourceRAmt);
									   balance.setCurrentbalance(amount + sourceRAmt);
								   }
								   else
								   {
									   balance.setOpeningbalance(amount - sourcePAmt);
									   balance.setCurrentbalance(amount - sourcePAmt);
								   }
							   }
							   else
							   {
								   if(detail.getSourceReceivableAmt() !=0)
								   {
									   balance.setOpeningbalance(balance.getOpeningbalance()+ sourceRAmt);
									   balance.setCurrentbalance(balance.getCurrentbalance()+ sourceRAmt);
								   }
								   else
								   {
									   balance.setOpeningbalance(balance.getOpeningbalance()- sourcePAmt);
									   balance.setCurrentbalance(balance.getCurrentbalance()- sourcePAmt);
								   }
							   }
					       branchBalanceDAO.update(balance);
					      }
						  else
						   {
							   balance = new BranchBalance();
							   balance.setBranchbalance_id(KeyGenerator.generateKey(getConnection()));
							   balance.setBranch_id(detail.getBranchId());
							   balance.setCurrencyid(detail.getCurrencyId());
							   if(detail.getSourceReceivableAmt() !=0 )
							   {
								   balance.setOpeningbalance(+sourceRAmt);
								   balance.setCurrentbalance(+sourceRAmt);
							   }
							   else
							   {
								   balance.setOpeningbalance(-sourcePAmt);
								   balance.setCurrentbalance(-sourcePAmt);
							   }
							   branchBalanceDAO.create(balance);
						   }
					   }
//				   }
		
				   CurrencyRateDetail currencyrateDetail = new CurrencyRateDetail();
					if(detail.getRate() !=1){
						currencyrateDetail = rateDetailDAO.findLatest(detail.getCurrencyRateId());
						if (currencyrateDetail.getRate() != detail.getRate())
						{
							currencyrateDetail.setCurrencyRateDetailId(KeyGenerator.generateKey(getConnection()));
						    currencyrateDetail.setCurrencyRateId(detail.getCurrencyRateId());
							currencyrateDetail.setRate(detail.getRate());
							currencyrateDetail.seteDateTime(new Date());
							rateDetailDAO.create(currencyrateDetail);
							
							 Log l_logentity = new Log();
							   l_logentity.setTablename("CurrencyRateDetail");
							   l_logentity.setLogkey(KeyGenerator.generateKey(getConnection()));
							   l_logentity.setKey(l_currencyrateDetail.getCurrencyRateDetailId());
							   l_logentity.setLogstatus(Log.__SAVE_DATA);
							   logDAO.getData(l_logentity);
						}
					}
					
					   entity.setAllBranchOpeningId(detail.getAllBranchOpeningId());
					   detail.setDefaultBranchId(entity.getDefaultBranchId());
					   detail.setUserId(entity.getUserId());
					   allBranchOpeningDAO.update(detail);
					   
					   Log l_logentity = new Log();
						l_logentity.setTablename("AllBranchOpening");
						l_logentity.setLogkey(KeyGenerator.generateKey(getConnection()));
						l_logentity.setKey(detail.getAllBranchOpeningId());
						l_logentity.setUserid(entity.getUserId());
						l_logentity.setLogstatus(Log.__UPDATE_DATA);
						logDAO.getData(l_logentity);
			    }
			}
			commintTransaction();
		} catch (SQLException e) {
			rollbackTransaction();
			if (DataDuplicationException.UNIQUE_KEY_ERROR_CODE == e
					.getErrorCode())
				throw new DataDuplicationException(e.getMessage());
			else
				throw e;
		} finally {
			closeConnection();
		}
		}

	public void delete(AllBranchOpening allBranchOpening) throws Exception {
		openConnection();
		try{
			branchBalanceDAO = RemittanceDAOFactory.getBranchBalanceDAO(dbManager.getConnection());
			logDAO = CommonDAOFactory.getLogDAO(getConnection());
			
			for(AllBranchOpening detail : allBranchOpening.getAllBranchOpeningList())
			{
				BranchBalance branch = new BranchBalance();
				branch.setBranch_id(detail.getBranchId());
				branch.setCurrencyid(detail.getCurrencyId());
				branch = branchBalanceDAO.getInfo(branch);
				if(branch != null)
				{
					branch.setBranch_id(detail.getBranchId());
					branch.setCurrencyid(detail.getCurrencyId());
					if(detail.getSourceReceivableAmt() !=0)
					{
						branch.setOpeningbalance(branch.getOpeningbalance()-detail.getSourceReceivableAmt());
						branch.setCurrentbalance(branch.getCurrentbalance()-detail.getSourceReceivableAmt());
					}
					else
					{
						branch.setOpeningbalance(branch.getOpeningbalance()+detail.getSourcePayableAmt());
						branch.setCurrentbalance(branch.getCurrentbalance()+detail.getSourcePayableAmt());
					}
					branchBalanceDAO.update(branch);
					
					Log l_logentity = new Log();
					l_logentity.setTablename("AllBranchOpening");
					l_logentity.setLogkey(KeyGenerator.generateKey(getConnection()));
					l_logentity.setKey(detail.getAllBranchOpeningId());
					l_logentity.setUserid(allBranchOpening.getUserId());
					l_logentity.setLogstatus(Log.__DELETE_DATA);
					logDAO.getData(l_logentity);
				}
			}
			allBranchOpeningDAO = RemittanceDAOFactory.getAllBranchOpeningDAO(dbManager.getConnection());
			
			allBranchOpeningDAO.delete(allBranchOpening);
			
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public AllBranchOpening find(long key) throws Exception {
		openConnection();
		try{
			AllBranchOpening allBranchOpening = new AllBranchOpening();
			allBranchOpeningDAO = RemittanceDAOFactory.getAllBranchOpeningDAO(dbManager.getConnection());
			ArrayList<AllBranchOpening> l_grid = new ArrayList<AllBranchOpening>();
			l_grid = allBranchOpeningDAO.find(key);
			allBranchOpening.setAllBranchOpeningList(l_grid);
			return allBranchOpening;
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public AllBranchOpening getAllBranchOpening(AllBranchOpening branchOpening) throws Exception {
		openConnection();
		try {
			allBranchOpeningDAO = RemittanceDAOFactory.getAllBranchOpeningDAO(dbManager.getConnection());
			return allBranchOpeningDAO.getAllBranchOpening(branchOpening);
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public JasperPrint prepareAllBranchOpeningReport(AllBranchOpeningRpt info) throws Exception {
		openConnection();
		JasperPrint l_jsPrint = null;
		try {
			allBranchOpeningDAO = RemittanceDAOFactory.getAllBranchOpeningDAO(dbManager.getConnection());

			JRResultSetDataSource l_jrRS = new JRResultSetDataSource(allBranchOpeningDAO.prepareAllBranchOpeningReport(info));

			JasperReport l_jsRpt = (JasperReport) JRLoader
					.loadObjectFromFile(CommonSingleton.ABSOLUTE_PATH
							+ "reports/AllBranchOpeningRpt.jasper");
			HashMap<String, Object> l_params = new HashMap<String, Object>();
			l_params.put("company", "MBC");
			l_jsPrint = JasperFillManager.fillReport(l_jsRpt, l_params, l_jrRS);

		} catch (JRException je) {
			throw je;
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}

		return l_jsPrint;

	}
}